
export class ArrayUniqueUtils {

  static uniqueByKey<T>(array: T[], key: keyof T): T[] {
    const seen = new Set<any>();
    return array.filter(item => {
      const value = item[key];
      if (seen.has(value)) {
        return false;
      }
      seen.add(value);
      return true;
    });
  }


  static uniqueByStringify<T>(array: T[]): T[] {
    const seen = new Set<string>();
    return array.filter(item => {
      const str = JSON.stringify(item);
      if (seen.has(str)) {
        return false;
      }
      seen.add(str);
      return true;
    });
  }


  static uniqueByCompare<T>(array: T[], compareFn: (a: T, b: T) => boolean): T[] {
    return array.filter((item, index, self) => {
      return index === self.findIndex(t => compareFn(t, item));
    });
  }


  static uniqueByMultipleKeys<T>(array: T[], keys: (keyof T)[]): T[] {
    const seen = new Set<string>();
    return array.filter(item => {
      const keyValues = keys.map(k => item[k]).join('|');
      if (seen.has(keyValues)) {
        return false;
      }
      seen.add(keyValues);
      return true;
    });
  }
}
